<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>color-triangle</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }

        canvas {
            border: 3px solid blue;
            /*width: 100vw;*/
            /*height: 100vh;*/
            display: block;
        }

        #gui {
            position: absolute;
            left: 820px;
            top: 10px;
        }
    </style>
</head>
<body>
<script type="text/javascript" src="../libs/webgl-utils.js"></script>
<script type="text/javascript" src="../libs/shader.js"></script>
<script type="text/javascript" src="../libs/m3.js"></script>
<script type="text/javascript" src="../libs/dat.gui.min.js"></script>

<canvas id="color-triangle" width="800" height="600"></canvas>
<div id="gui"></div>

   <script id="vertex-shader" type="x-shader/vertex">
        attribute vec2 a_position;
        uniform mat3 u_matrix;
        varying vec4 v_color;

        void main() {
            gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy * 0.8, 0, 1);
            v_color = gl_Position * 0.5 + 0.5;
        }
   </script>

   <script id="fragment-shader" type="x-shader/x-fragment">
        precision mediump float;
        varying vec4 v_color;
        void main() {
            gl_FragColor = v_color;
        }
   </script>
   <script>
        "use strict";
        function main() {
            let canvas = document.getElementById('color-triangle');

            //判断浏览器是否支持webgl
            let gl = canvas.getContext('webgl', {antialias: true, depth: false});
            if (!gl) {
                console.log("您的浏览器不支持webgl！");
            }

            //获取GLSL的字符串
            let vertexShaderSource = document.getElementById('vertex-shader').text;
            let fragmentShaderSource = document.getElementById('fragment-shader').text;

            //创建着色器，加载着色器代码，编译着色器
            let vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
            let fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
            //链接着色器
            let program = createProgram(gl, vertexShader, fragmentShader);

            //在着色器中寻找attribute变量位置
            let positionAttributeLocation = gl.getAttribLocation(program, 'a_position');


            //在着色器中找uniform变量位置
            let matrixLocation = gl.getUniformLocation(program, 'u_matrix');

            //创建缓冲区
            let positionBuffer = gl.createBuffer();
            //将它绑定到ARRAY_BUFFER（将其视为ARRAY_BUFFER = positionBuffer）
            //绑定缓冲区
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

            let positions = [
                0, -100,
                150, 125,
                -175, 100
            ];

            setGeometry(gl, positions);

            let translation = [200, 150];
            let angleInRadians = 0;
            let scale = [1, 1];

            drawScene();

            //菜单栏
            let guiFiles = {
                "平移X": 200,
                "平移Y": 150,
                "旋转角度": 0,
                "缩放X方向": 1,
                "缩放Y方向": 1
            };

            let gui = new dat.GUI();
            gui.add(guiFiles, "平移X", 0, gl.canvas.width).onChange(function (e) {
                translation[0] = e;
                drawScene();
            });
            gui.add(guiFiles, "平移Y", 0, gl.canvas.width).onChange(function (e) {
                translation[1] = e;
                drawScene();
            });
            gui.add(guiFiles, "旋转角度", -360, 360).onChange(function(e) {
                angleInRadians = e * Math.PI / 180;
                drawScene();
            });
            gui.add(guiFiles, "缩放X方向", -5, 5).onChange(function(e) {
                scale[0] = e;
                drawScene();
            });
            gui.add(guiFiles, "缩放Y方向",-5, 5).onChange(function(e) {
                scale[1] = e;
                drawScene();
            });

            let ui = document.getElementById('gui');
            ui.appendChild(gui.domElement);


            //绘制场景
            function drawScene() {

                //使画布的像素数和显示大小匹配
                webglUtils.resizeCanvasToDisplaySize(gl.canvas);

                //设置视口
                gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

                //清除canvas
                gl.clearColor(0, 0, 0, 0);
                gl.clear(gl.COLOR_BUFFER_BIT);

                //应用着色器
                gl.useProgram(program);

                //建立着色器中attribute变量与缓冲区之间的连接
                gl.enableVertexAttribArray(positionAttributeLocation);

                gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

                const size = 2;//2维坐标：每次迭代运行提取两个单位数据
                const type = gl.FLOAT;//每个单位的数据类型是32位浮点型
                const normalize = false;//不需要归一化数据
                const stride = 0;//每次迭代前进大小* sizeof（类型）以获得下一个位置
                const offset1 = 0;//从缓冲起始位置开始读取

                //从缓冲区取出数据
                gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset1);

                //计算矩阵
                let matrix = m3.projection(gl.canvas.clientWidth, gl.canvas.clientHeight);
                matrix = m3.translate(matrix, translation[0], translation[1]);
                matrix = m3.rotate(matrix, angleInRadians);
                matrix = m3.scale(matrix, scale[0], scale[1]);

                gl.uniformMatrix3fv(matrixLocation, false, matrix);

                let primitiveType = gl.TRIANGLES;
                let offset2 = 0;
                let count = 3;
                gl.drawArrays(primitiveType, offset2, count);//画图
            }
        }

        //通过绑定点向缓冲区绑定数据
        function setGeometry(gl, positions) {
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
        }
        main();

    </script>
</body>
</html>